#include "stdafx.h"
#include "ULHook.h"  
  
CULHook::CULHook(LPSTR lpszModName, LPSTR lpszFuncNme, PROC pfnHook)  
{  
    BYTE btNewBytes[] = {0xB8, 0x00, 0x00,0x40,0x00,0xFF,0xE0,0x00};  
    memcpy(m_btNewBytes, btNewBytes, 8);  
    *(DWORD*)(m_btNewBytes+1) = (DWORD)pfnHook;  
  
    m_hModule = ::LoadLibraryA(lpszModName);  
    if (NULL == m_hModule)  
    {  
        m_pfnOrig = NULL;  
        return;  
    }
    m_pfnOrig = (PROC)::GetProcAddress(m_hModule, lpszFuncNme);  
    if (NULL != m_pfnOrig)  
    {  
        MEMORY_BASIC_INFORMATION mbi = {0};  
        DWORD dwOldProtect;  
        ::VirtualQuery(m_pfnOrig, &mbi, sizeof(mbi));  
        ::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);  
        memcpy(m_btOldBytes, m_pfnOrig, 8);  
        ::WriteProcessMemory(GetCurrentProcess(), (VOID*)m_pfnOrig, m_btNewBytes, 8, NULL);  
        ::VirtualProtect(m_pfnOrig, 8, dwOldProtect, NULL);  
    }
}

CULHook::CULHook(PROC pfnOrig, PROC pfnHook)
{
	BYTE btNewBytes[] = { 0xB8, 0x00, 0x00,0x40,0x00,0xFF,0xE0,0x00 };
	memcpy(m_btNewBytes, btNewBytes, 8);
	*(DWORD*)(m_btNewBytes + 1) = (DWORD)pfnHook;

	m_hModule = NULL;
	m_pfnOrig = pfnOrig;
	if (NULL != m_pfnOrig)
	{
		MEMORY_BASIC_INFORMATION mbi = { 0 };
		DWORD dwOldProtect;
		::VirtualQuery(m_pfnOrig, &mbi, sizeof(mbi));
		::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);
		memcpy(m_btOldBytes, m_pfnOrig, 8);
		::WriteProcessMemory(GetCurrentProcess(), (VOID*)m_pfnOrig, m_btNewBytes, 8, NULL);
		::VirtualProtect(m_pfnOrig, 8, dwOldProtect, NULL);
	}
}

CULHook::~CULHook(void)  
{  
    UnHook();  
    if (m_hModule!=NULL)  
    {  
        ::FreeLibrary(m_hModule);  
    }
}
void CULHook::UnHook()  
{  
    if (m_pfnOrig != NULL)  
    {  
        MEMORY_BASIC_INFORMATION mbi = {0};  
        DWORD dwOldProtect;  
        ::VirtualQuery(m_pfnOrig, &mbi, sizeof(mbi));  
        ::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);  
        ::WriteProcessMemory(GetCurrentProcess(), (VOID*)m_pfnOrig, m_btOldBytes, 8, NULL);  
        ::VirtualProtect(m_pfnOrig, 8, dwOldProtect, NULL);  
    }
}
  
void CULHook::ReHook()  
{  
    if (m_pfnOrig != NULL)  
    {  
        MEMORY_BASIC_INFORMATION mbi = {0};  
        DWORD dwOldProtect;  
        ::VirtualQuery(m_pfnOrig, &mbi, sizeof(mbi));  
        ::VirtualProtect(m_pfnOrig, 8, PAGE_READWRITE, &dwOldProtect);  
        ::WriteProcessMemory(GetCurrentProcess(), (VOID*)m_pfnOrig, m_btNewBytes, 8, NULL);  
        ::VirtualProtect(m_pfnOrig, 8, dwOldProtect, NULL);  
    }
}